package xorm

import (
	"gitee.com/KotlinToGo/xorm/schema"
	"reflect"
	"strings"
	"time"
)

func setColumnInt(bean interface{}, col *schema.Column, t int64) {
	v, err := col.ValueOf(bean)
	if err != nil {
		return
	}
	if v.CanSet() {
		switch v.Type().Kind() {
		case reflect.Int, reflect.Int64, reflect.Int32:
			v.SetInt(t)
		case reflect.Uint, reflect.Uint64, reflect.Uint32:
			v.SetUint(uint64(t))
		}
	}
}

func setColumnTime(bean interface{}, col *schema.Column, t time.Time) {
	v, err := col.ValueOf(bean)
	if err != nil {
		return
	}
	if v.CanSet() {
		switch v.Type().Kind() {
		case reflect.Struct:
			v.Set(reflect.ValueOf(t).Convert(v.Type()))
		case reflect.Int, reflect.Int64, reflect.Int32:
			v.SetInt(t.Unix())
		case reflect.Uint, reflect.Uint64, reflect.Uint32:
			v.SetUint(uint64(t.Unix()))
		}
	}
}

func getFlagForColumn(m map[string]bool, col *schema.Column) (val bool, has bool) {
	if len(m) == 0 {
		return false, false
	}

	n := len(col.Name)

	for mk := range m {
		if len(mk) != n {
			continue
		}
		if strings.EqualFold(mk, col.Name) {
			return m[mk], true
		}
	}

	return false, false
}

func col2NewCols(columns ...string) []string {
	newColumns := make([]string, 0, len(columns))
	for _, col := range columns {
		col = strings.Replace(col, "`", "", -1)
		col = strings.Replace(col, `"`, "", -1)
		ccols := strings.Split(col, ",")
		for _, c := range ccols {
			newColumns = append(newColumns, strings.TrimSpace(c))
		}
	}
	return newColumns
}

// Incr 提供查询字符串，例如“ count = count + 1”
func (s *Session) Incr(column string, arg ...interface{}) *Session {
	s.statement.Incr(column, arg...)
	return s
}

// Decr 提供查询字符串，例如“ count = count-1”
func (s *Session) Decr(column string, arg ...interface{}) *Session {
	s.statement.Decr(column, arg...)
	return s
}

// SetExpr 提供查询字符串，例如“ column = {expression}”
func (s *Session) SetExpr(column string, expression interface{}) *Session {
	s.statement.SetExpr(column, expression)
	return s
}

// Select 指定一些列(通过一个字符串的形式)
func (s *Session) Select(str string) *Session {
	s.statement.Select(str)
	return s
}

// Pluck (原Cols) 指定单个单个的列。
func (s *Session) Field(columns ...string) *Session {
	s.statement.Field(columns...)
	return s
}

// AllCols 指定所有的列
func (s *Session) AllCols() *Session {
	s.statement.AllCols()
	return s
}

// MustCols 指定一些列，即使它们为空也必须使用。
func (s *Session) MustField(columns ...string) *Session {
	s.statement.MustField(columns...)
	return s
}

// UseBool 自动根据struct检索条件时，使用 UseBool 告诉系统不要忽略struct中的bool字段。
//
// 如果没有参数(即<columns为空>)，它将使用struct的所有bool字段，或者将使用参数的列。
func (s *Session) UseBool(columns ...string) *Session {
	s.statement.UseBool(columns...)
	return s
}

// Distinct 用于不同的列. 注意：使用高速缓存时，由于高速缓存系统需要id，所以distinct将不会被高速缓存，但是distinct将不会提供id
func (s *Session) Distinct(columns ...string) *Session {
	s.statement.Distinct(columns...)
	return s
}

// Omit 仅不将参数用作选择或更新列。参数<columns>是被忽略的列。
func (s *Session) Omit(columns ...string) *Session {
	s.statement.Omit(columns...)
	return s
}

// Nullable 当列为零值且可为更新时可为null时设置为null。
func (s *Session) Nullable(columns ...string) *Session {
	s.statement.Nullable(columns...)
	return s
}

// NoAutoTime 表示不会临时自动将当前会话的当前时间提供给创建字段和更新字段
func (s *Session) NoAutoTime() *Session {
	s.statement.UseAutoTime = false
	return s
}
